package pe.com.bbva.carga.bo.impl;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import pe.com.bbva.carga.bo.ProcesoCargaBO;
import pe.com.bbva.carga.dao.ProcesoCargaDAO;
import pe.com.bbva.carga.domain.ProcesoCarga;
import pe.com.bbva.targps.bo.TarjetaBO;
import pe.com.bbva.targps.domain.ConsultaGPS;
import pe.com.bbva.targps.domain.Tarjeta;
import pe.com.bbva.util.Constantes;
import pe.com.stefanini.core.bo.GenericBOImpl;
import pe.com.stefanini.core.bo.Grid;
import pe.com.stefanini.core.domain.UsuarioSession;
import pe.com.stefanini.core.exceptions.BOException;
import pe.com.stefanini.core.exceptions.DAOException;
import pe.com.stefanini.core.util.FechaUtil;
import pe.com.stefanini.core.util.StringUtil;

@Service("procesoCargaBO")
@SuppressWarnings({"rawtypes", "unchecked"})
public class ProcesoCargaBOImpl extends GenericBOImpl implements ProcesoCargaBO{
	Logger logger = Logger.getLogger(this.getClass());
	@Resource
	private ProcesoCargaDAO procesoCargaDAO;
	
	@Resource
	private TarjetaBO tarjetaBO;

	@Transactional(propagation=Propagation.REQUIRED)
	public void save(ProcesoCarga procesoCarga) throws BOException, DAOException {
		super.doSave(procesoCarga);
	}
	
	public void update(ProcesoCarga procesoCarga) throws BOException {			
		try {
			super.doSave(procesoCarga);
		} catch (Exception e) {
			logger.error(StringUtil.getStackTrace(e));
			throw new BOException(e.getMessage());
		}
	}
	
	public ProcesoCarga findById(Long id) throws BOException {
		ProcesoCarga procesoCarga = (ProcesoCarga) super.findById(ProcesoCarga.class, id);
		return procesoCarga;
	}

	public List<ProcesoCarga> findProcesosCarga(ProcesoCarga procesoCarga) throws BOException, DAOException {
		List<ProcesoCarga> listaProcesos = procesoCargaDAO.findProcesosCarga(procesoCarga);
		return listaProcesos;
	}
	
	public List<ProcesoCarga> findProcesosCargaRango(ProcesoCarga procesoCarga, String fechaInicio, String fechaFin)throws BOException, DAOException {
		List<ProcesoCarga> listaProcesos = procesoCargaDAO.findProcesosCargaRango(procesoCarga, fechaInicio, fechaFin);
		return listaProcesos;
	}
	
	public Grid<ProcesoCarga> findToGrid(ProcesoCarga procesoCarga, String order, int page, int rows) throws BOException, DAOException {
		String where="where ";	
		List<ProcesoCarga> listaProcesos= findProcesosCarga(procesoCarga);
	    return super.findToGridList(listaProcesos, where, " order by "+order,page,rows);
	}
	
	public Grid<ConsultaGPS> findToGridGPS(List<ConsultaGPS> consultas, String order, int page, int rows) throws BOException, DAOException {
		String where="where ";
	    return super.findToGridList(consultas, where, " order by "+order,page,rows);
	}
	
	@Transactional(propagation=Propagation.REQUIRED , rollbackFor ={BOException.class})
	public Long  ValidaCargaEnProceso() throws BOException {
		Long idArchivo = 0L;		
		try {
			idArchivo = procesoCargaDAO.ValidaCargaEnProceso();
		} catch (DAOException e) {
			logger.error(StringUtil.getStackTrace(e));
			throw new BOException(e.getMessage());
		}
		return idArchivo;
	}
	
	public List<String> consolidarCarga(Long idTurno, String fechaProceso){
		try {								
			List<String> lstEquipos = new ArrayList<String>();
			lstEquipos = procesoCargaDAO.consolidarCarga(idTurno,fechaProceso);
			return lstEquipos;
					
		} catch (Exception e) {
			return null;
		}
	}

	public void delete(ProcesoCarga procesoCarga) throws BOException {
		super.delete(procesoCarga);
	}
	
	public void cambiaFacturado(ProcesoCarga proceso, UsuarioSession usuario)throws DAOException, BOException{
		int sumatoriaTarjetas = 0;
		Tarjeta tarjetaBuscar = new Tarjeta();
		
		tarjetaBuscar.setIdProcesoCarga(proceso.getId());
		List<Tarjeta> tarjetasTotalProceso = tarjetaBO.findTarjetas(tarjetaBuscar);
		
		tarjetaBuscar.setIdProcesoCarga(proceso.getId());
		tarjetaBuscar.setEstado(Constantes.ESTADO_TARJETA_ENTREGADO.toString());
		List<Tarjeta> tarjetasEntregado = tarjetaBO.findTarjetas(tarjetaBuscar);
		
		
		tarjetaBuscar.setIdProcesoCarga(proceso.getId());
		tarjetaBuscar.setEstado(Constantes.ESTADO_TARJETA_NO_ENTREGADO.toString());
		List<Tarjeta> tarjetasNoEntregado = tarjetaBO.findTarjetas(tarjetaBuscar);

		tarjetaBuscar.setIdProcesoCarga(proceso.getId());
		tarjetaBuscar.setEstado(Constantes.ESTADO_TARJETA_NO_ESTAMPADO.toString());
		List<Tarjeta> tarjetasNoEstampado = tarjetaBO.findTarjetas(tarjetaBuscar);
		
		sumatoriaTarjetas = tarjetasEntregado.size()+tarjetasNoEntregado.size()+tarjetasNoEstampado.size();
		
		if(sumatoriaTarjetas == tarjetasTotalProceso.size()){
			tarjetaBuscar = new Tarjeta();
			tarjetaBuscar.setEstadoFacturacion(String.valueOf(Constantes.ESTADO_PROCESO_FACTURADO));
			tarjetaBuscar.setEstado(Constantes.ESTADO_TARJETA_ENTREGADO.toString());
			tarjetaBuscar.setIdProcesoCarga(proceso.getId());
			List<Tarjeta> tarjetasFacturadas = tarjetaBO.findTarjetas(tarjetaBuscar);
			
			if(tarjetasEntregado.size() == tarjetasFacturadas.size()){
				if(usuario==null){
					proceso.setCodUsuarioModificacion("ADMIN");
					proceso.setFormaFacturacion(Constantes.ID_TIPO_CARGA_AUTOMATICO.toString());
				}else{
					proceso.setCodUsuarioModificacion(usuario.getCodigo());
					proceso.setFormaFacturacion(Constantes.ID_TIPO_CARGA_MANUAL.toString());
				}
				proceso.setFechaModificacion(FechaUtil.getFechaActualDate());//Fecha de Facturacion del proceso
				proceso.setEstadoFacturacion(String.valueOf(Constantes.ESTADO_PROCESO_FACTURADO));
				this.doSave(proceso);
			}else{
				logger.info("El total de tarjetas del proceso:"+proceso.getId()+" no ha sido facturado.");
			}
		}
	}
}